14

即时通讯

即时通讯是一种客户端与服务端的通信服务,例如聊天,消息推送等,方式有三种:

  • node内置net模块实现的通信方式
  • WebSocket的通信方式
  • Socket.io的通信方式

这三种通信方式都很类似,
服务端:

1、创建服务
2、创建连接 拿到客户端信息
3、服务端广播数据给各个客户端
4、服务端关闭连接

客户端:

1、客户端连接服务器
2、客户端发送数据
3、客户端接受服务端数据

Websocket实现简单聊天窗口

1、服务端 新建文件WsServer.js

//1、创建服务
var WebsocketServer = require('ws').Server
var wss = new WebsocketServer({port: 9000})
//
var clientMap = new Object()
var i = 0
wss.on('connection',funciton(ws){
    console.log(ws + '上线啦')
    ws.name = ++i
    clientMap[ws.name] = ws
    //接收客户端数据
    ws.on('message',function(msg){
        broadcast(msg, ws)
    })
    //客户端关闭监听
    ws.on('close',function(){
        delete clientMap[ws.name]
        console.log(ws.name + '离开')
    })
})
function broadcast(msg, ws){
    for(var key in clientMap){
        clientMap[key].send(ws.name + '说' + msg)
    }
}

2、客户端 新建html页面

index.html
<h1>Websocket</h1>
<div id='chatroom'></div>
<input type="text" name= "sayinput" id='sayinput' value/>
<input type="button" name="send" id="send" value="发送">

<script src="./wsClient.js"></script>
<script>
    function send(){
        var sayinput = document.querySelector('#sayinput')
        ws.send(sayinput.value)      //发送信息
        sayinput.value = ''
    }
    document.querySelector('#send').onclick = function(){
        send()
    }
    document.body.onkeup = function(event){
        if(event.keyCode == 13){
            send()
        }
    }
</script> 

3、客户端wsClient.js

var ws = new WebSocket('ws://10.0.0.1:9000/')
ws.onopen = function(){
    ws.send('大家好')
}
ws.onmessage = function(event){
    var chatroom = document.querySelector('#chatroom')
    chatroom.innerHTML += '<br/>' + event.data
}
ws.onclose = function(){
    console.log('closed')
}
ws.onerr = function(err){
    console.log(err)
}

在html中引入wsClient.js
启动服务端 node WsServer.js
npm init 
cnpm i ws -D  

socket.io

Websocket毕竟是H5新出的,有浏览器的兼容性,所以我们一般用socket.io这种通讯方式,支持websocket的通信协议,又可以兼容ie浏览器

(1) 服务端
启动一个node服务,并绑定connection事件来链接客户端
www 中配置

var http = require('http')
var server = http.createServer(app)  //启动一个服务

var io =  require('socket.io')(server)
var broadcast = require('./broadcast')
var clients = {}
var count = 0;
io.on('connection',(socket)=>{
    socket.name = ++count;
    clients[socket.name] = socket
    
    socket.on('disconnect',()=>{
        delete clients[socket.name]     //断开链接
    })
})

//如何将服务器的数据派发到各个客户端呢,我们这里定义一个broadcast中间事件

broadcast.js

const EventEmitter = require('events').EventEmitter
let broadcast = Object.assign({},EventEmitter.prototype)
module.exports = broadcast

www

broadcast.on('hahaha',function(message){    //将服务端的信息分发给各个客户端
    for(var name in clients){
        clients[name].send(message)
    }
})

//如何使用呢?当服务端有新的消息时,我们应该如何订阅到客户端

这里,如果我新添加一条商品,客户端要实时接收到有新商品了
willSaveProducts.save().then(()=>{
    broadcast.emit('hahaha','xin')
    console.log('添加成功')
    res.json(getParam({success:true}))
})

(2) 客户端
定义bus总线,进行传参

import Vue from 'vue'
const event_bus = new Vue()
export default event_bus

建立链接 并接受服务端传过来的信息

import bus from '../event_bus'
const socket = io.connect('http://localhost:3000')

socket.on('message',(message)=>{
    bus.$emit(message)
})

组件 调用 接收传过来的参数 根据参数来响应

main.vue

import bus from '../../event_bus'

export default {
    data(){
        return {
            isHasNew = false
        }
    },
    mounted(){
        bus.$on('xin', function () {    //接收到服务器端有新数据,那我就提示有新数据楼
            this.isHasNew = true
        }.bind(this))
    }
    ...
}

Cymiran
1.2k 声望134 粉丝

跨越七海的风...